package com.data.mv.controller;

import com.data.mv.mappers.mysql.MysqlMapper;
import com.data.mv.mappers.oracle.OracleMapper;
import com.data.mv.sql.SqlCreateTable;
import com.data.mv.sql.SqlInsertTable;
import com.data.mv.sql.SqlSelectTable;
import com.data.mv.sql.SqlUtils;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.TimeUnit;

@RestController
public class MvController {
    @Autowired
    MysqlMapper mysqlMapper;
    @Autowired
    OracleMapper oracleMapper;

    @RequestMapping("/tableInfo")
    public String tableInfo() {
        oracleMapper.getTableInfo().stream().forEach(e -> {
            SqlUtils.addTableDefinition(e);
            SqlUtils.addDataType(e);
        });
        return "ok";
    }

    @RequestMapping("/syncTableInfo")
    public String syncTableInfo() {
        oracleMapper.getSyncTableInfo().stream().forEach(e -> {
            SqlUtils.addTableDefinition(e);
            SqlUtils.addDataType(e);
        });
        return "ok";
    }

    @RequestMapping("/countTable")
    public String countTable() {
        SqlUtils.getTableDefinition().forEach((k, v) -> {
            try {
                SqlUtils.setTableCount(k, oracleMapper.countTable(k));
            } catch (Exception e) {
                e.printStackTrace();
            }
            SqlUtils.addTableColumn(k, v);
        });
        return "ok";
    }

    @RequestMapping("/createTable")
    public String createTable() {
        SqlUtils.getTableDefinition().forEach((k, v) -> {
            if (!CollectionUtils.isEmpty(SqlUtils.getTableCount()) && Objects.nonNull(SqlUtils.getTableCount().get(k))) {
                mysqlMapper.createTable(SqlCreateTable.create(k, v).toLowerCase());
            }
        });
        return "ok";
    }

    @RequestMapping("/dropTable")
    public String dropTable() {
        SqlUtils.getTableCount().forEach((k, v) -> {
            mysqlMapper.dropTable(k);
        });
        return "ok";
    }

    @Async
    @RequestMapping("/insert")
    public String insert() {
        SqlUtils.getTableColumn().forEach((k, v) -> {
            pool.execute(() -> {
                List<Integer> pages=SqlUtils.getPages(k);
                if(Objects.nonNull(pages)) {
                    pages.parallelStream().forEach(e -> {
                        PageHelper.startPage(e, SqlUtils.PAGE_SIZE);
                        List<Map<String, Object>> data = oracleMapper.select(SqlSelectTable.select(k, v));
                        if (!CollectionUtils.isEmpty(data)) {
                            mysqlMapper.insert(SqlInsertTable.insert(k, v, data));
                        }
                    });
                }
            });
        });
        return "ok";
    }

    @RequestMapping("/delete")
    public String delete() {
        SqlUtils.getTableColumn().forEach((k, v) -> {
            mysqlMapper.delete(k);
        });
        return "ok";
    }

    @Async
    @RequestMapping("/checkOver")
    public String checkOver() {
        boolean loop[] = {true};
        while (loop[0]) {

            try {
                TimeUnit.MINUTES.sleep(1);
            } catch (InterruptedException e) {
            }

            loop[0] = false;

            SqlUtils.getTableCount().forEach((k, v) -> {
                if (!SqlUtils.checkOver(k, mysqlMapper.countTable(k))) {
                    loop[0] = true;
                }
            });
            System.out.println("检测一次");

        }
        System.out.println("---------迁移结束------------");
        return "ok";
    }

    @Qualifier("pool")
    @Autowired
    private ForkJoinPool pool;
}
